home *** CD-ROM | disk | FTP | other *** search
- /*----------------------------------------------------*
- | File: VLTIMER.c - Small clock/timer for the Amiga. |
- | Version: 2.00 (no version string to save space :-) |
- | Last modified: MLO 30 Nov 1993 20:21:09 |
- +----------------------------------------------------+-----------*
- | This code is free software, that you can distribute and modify |
- | under the terms of the GNU General Public License (included in |
- | the file LICENSE.TXT of the distribution) -- see also the file |
- | DISCLAIMER.TXT, about the (lack of) warranties and the author. |
- *----------------------------------------------------------------*/
-
- /**
- | VLTimer opens a small window with a digital clock/timer in the
- | VLT custom screen (or in the default Public Screen). The timer
- | can be reset selecting the window and hitting the '0' key; the
- | 'TAB' key switches between clock and timer.
- **/
-
- /**
- | #include's
- **/
-
- #include <stdio.h> /* Standard library */
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
- #include <exec/types.h> /* Amiga stuff */
- #include <exec/memory.h>
- #include <workbench/startup.h>
- #include <proto/exec.h>
- #include <proto/dos.h>
- #include <proto/icon.h>
- #include <proto/intuition.h>
-
- /**
- | Global variables to detach from CLI
- **/
-
- long __stack = 4000;
- char *__procname = "VLTimer";
- long __priority = 0;
- long __BackGroundIO = 0;
-
- /**
- | Global variables to be addressed by Cleanup()
- **/
-
- struct IntuitionBase *IntuitionBase = 0;
- struct Screen *pScreen = 0;
- struct Window *Window = 0;
- struct IntuiMessage *pIM = 0;
- struct Library *IconBase = 0;
- struct RDArgs *pRDArgs = 0;
-
- /**
- | #define's:
- | - miscellaneous parameters;
- | - flags and IDCMP's for the VLTimer window;
- **/
-
- #define REVISION 37 /* Library revision (AmigaDOS 2.04) */
- #define W_WIDTH 58 /* Window width (text excluded) */
- #define NO_TIME ((ULONG) ~0) /* Flag 'no time on screen' */
- #define DELTA 10 /* Sleep time (DELTA/50 seconds) */
- #define ZERO '0' /* ASCII zero */
- #define TAB '\t' /* ASCII TAB */
-
- #define W_IDCMP IDCMP_CLOSEWINDOW | IDCMP_VANILLAKEY
- #define W_FLAG1 WFLG_CLOSEGADGET | WFLG_DRAGBAR | WFLG_DEPTHGADGET
- #define W_FLAG2 WFLG_SIMPLE_REFRESH
- #define W_FLAGS (W_FLAG1 | W_FLAG2)
-
- /**
- | CLI command line template, and constants for ReadArgs
- **/
-
- #define TEMPLATE "PUBSCREEN/K,CLOCK/S"
-
- enum eOptions {
- OPTION_SCREEN = 0,
- OPTION_CLOCK,
- N_OPTIONS /* This must be last */
- };
-
- /**
- | ANSI procedures prototypes
- **/
-
- void Cleanup(int ReturnCode);
- void NtoA(char *buf, int h, int m, int s);
-
- /**
- | The main program.
- | If something goes wrong, VLTimer exits silently setting the
- | return code for the CLI to 20 (EXIT_FAILURE).
- **/
-
- int main(
- int argc,
- char *argv[]
- ){
- unsigned int Start[2]; /* When the timer was started */
- int dispClock; /* Clock/Timer flag */
-
- ULONG Last = NO_TIME; /* Last printed time */
- char slate[] = "hh:mm:ss"; /* Print buffer */
- char *pScreenName = 0; /* Public Screen name */
-
- struct NewWindow NWind = { /* VLTimer window parameters */
- 0, 0, W_WIDTH, 0,
- 0, 1,
- W_IDCMP,
- W_FLAGS,
- 0, 0,
- (UBYTE *) "",
- 0, 0,
- 0, 0, 0, 0,
- PUBLICSCREEN
- };
-
- /**
- | Opens the intuition library
- **/
-
- if ((IntuitionBase = (struct IntuitionBase *)
- OpenLibrary("intuition.library", REVISION)) == 0) {
- exit(EXIT_FAILURE);
- }
-
- /**
- | Allocates an IntuiMessage buffer
- **/
-
- if ((pIM = AllocMem(sizeof(struct IntuiMessage), MEMF_ANY)) == 0) {
- Cleanup(EXIT_FAILURE);
- }
-
- /**
- | If called from the CLI, parses the command line; if started from
- | the workbench, gets the tool types. In both cases, looks for:
- | - 'PUBSCREEN=<name>', to define the screen where the VLTimer
- | window will be opened, if different from the default public
- | screen);
- | - 'CLOCK', to start in the clock mode (the default is the timer
- | mode).
- | If an error is detected parsing the tool types or the command
- | line, the default values are used for the public screen and the
- | starting mode.
- **/
-
- if (argc) {
- long options[(int) N_OPTIONS];
-
- memset(options, 0, sizeof(options));
-
- if ((pRDArgs = ReadArgs(TEMPLATE, options, 0)) != 0) {
- pScreenName = (char *) options[(int) OPTION_SCREEN];
- dispClock = options[(int) OPTION_CLOCK];
- }
- } else {
- struct WBArg *pWBA;
- struct DiskObject *pDO;
-
- if ((IconBase = OpenLibrary("icon.library", REVISION)) == 0) {
- Cleanup(EXIT_FAILURE);
- }
-
- pWBA=((struct WBStartup *) argv)->sm_ArgList;
-
- if (pWBA->wa_Name != 0 && (pDO = GetDiskObject(pWBA->wa_Name)) != 0) {
- pScreenName = (char *)
- FindToolType((char **) pDO->do_ToolTypes, "PUBSCREEN");
- dispClock =
- (FindToolType((char **) pDO->do_ToolTypes, "CLOCK") != 0);
- FreeDiskObject(pDO);
- }
- }
-
- /**
- | Locks the target screen, and opens the window (after having
- | adjusted the NewWindow parameters, considering the screen font,
- | to open the window in its lower right corner). Yes, I know, YOU
- | don't like that position---but I do...
- **/
-
- if ((pScreen = LockPubScreen(pScreenName)) == 0) {
- Cleanup(EXIT_FAILURE);
- }
-
- NWind.Screen = pScreen;
- NWind.LeftEdge = pScreen->Width -
- (NWind.Width += pScreen->RastPort.TxWidth * 8);
- NWind.TopEdge = pScreen->Height -
- (NWind.Height = pScreen->WBorTop + pScreen->RastPort.TxHeight + 1);
-
- if ((Window = OpenWindow(&NWind)) == 0) {
- Cleanup(EXIT_FAILURE);
- }
-
- /**
- | Starts the timer; then begins an infinite loop (exit closing the
- | window). Checks for Intuition event (window closed, or key hit),
- | and performs the appropriate action: resets the timer if the '0'
- | key has been hit, or switches between timer and clock if the 'TAB'
- | key has been hit). Then asks for the current time and, if the
- | display should has changed, updates it; then suspends itself for
- | a short time.
- **/
-
- for ((void) timer(Start); ; Delay(DELTA)) {
- struct IntuiMessage *IMsg; /* Intuition message pointer */
- int hour, mins, secs; /* Elapsed time */
- int oldSec; /* Last time clock was updated */
-
- while ((IMsg = (struct IntuiMessage *) GetMsg(Window->UserPort)) != 0) {
- memcpy(pIM, IMsg, sizeof(struct IntuiMessage));
- ReplyMsg((struct Message *) IMsg);
-
- switch (pIM->Class) {
- case IDCMP_CLOSEWINDOW:
- Cleanup(EXIT_SUCCESS);
- break;
-
- case IDCMP_VANILLAKEY:
- switch (pIM->Code) {
- case TAB:
- if ((dispClock = !dispClock) != 0) {
- oldSec = -1;
- }
- break;
-
- case ZERO:
- (void) timer(Start);
- break;
-
- }
- break;
-
- }
- }
-
- if (dispClock) {
- struct DateStamp ds;
-
- (void) DateStamp(&ds);
- secs = ds.ds_Tick / TICKS_PER_SECOND;
- if (secs != oldSec) {
- hour = ds.ds_Minute / 60;
- mins = ds.ds_Minute % 60;
- oldSec = secs;
- NtoA(slate, hour, mins, secs);
- SetWindowTitles(Window, slate, (UBYTE *) -1);
- }
- } else {
- unsigned int SysSecs[2];
-
- (void) timer(SysSecs);
- *SysSecs -= *Start;
- if (SysSecs[1] < Start[1]) (*SysSecs)--;
- if (*SysSecs != Last) {
- secs = (Last = *SysSecs) % 60;
- mins = (Last / 60) % 60;
- hour = (Last / 3600) % 24;
- NtoA(slate, hour, mins, secs);
- SetWindowTitles(Window, slate, (UBYTE *) -1);
- }
- }
- }
- }
-
- void Cleanup(
- int ReturnCode /* Exit code */
- ){
-
- /**
- | Releases all system resources, then exits.
- **/
-
- if (Window != 0) {
- void *IMsg;
-
- while ((IMsg = GetMsg(Window->UserPort)) != 0) {
- ReplyMsg(IMsg);
- }
- CloseWindow(Window);
- }
-
- if (pScreen != 0) UnlockPubScreen(0, pScreen);
- if (pRDArgs != 0) FreeArgs(pRDArgs);
- if (pIM != 0) FreeMem(pIM, sizeof(struct IntuiMessage));
- if (IconBase != 0) CloseLibrary(IconBase);
- if (IntuitionBase != 0) CloseLibrary((struct Library *) IntuitionBase);
-
- exit(ReturnCode);
- }
-
- void NtoA(
- char *buf, /* Output buffer */
- int h, /* Hours */
- int m, /* Minutes */
- int s /* Seconds */
- ){
- /**
- | Instead of sprintf(... "%02d:%02d:%02d" ...); to save memory.
- **/
-
- *buf++ = ZERO + ((h / 10) % 10);
- *buf++ = ZERO + (h % 10);
- buf++;
- *buf++ = ZERO + (m / 10);
- *buf++ = ZERO + (m % 10);
- buf++;
- *buf++ = ZERO + (s / 10);
- *buf = ZERO + (s % 10);
- }
-